/*********************************************************
          File Name:queue.c
          Author: Abby Cin
          Mail: abbytsing@gmail.com
          Created Time: Fri 15 Apr 2016 09:19:13 AM CST
**********************************************************/

#include "queue.h"

static size_t limit_queue_size;

static qNode* NewNode()
{
	qNode* res = (qNode*)malloc(sizeof(qNode));
	res->front = res;
	res->rear = res;
	res->size = 0;
	return res;
}

static int push_back(qNode* q, qNode* node)
{
	if(q->size >= limit_queue_size)
		return -1;
	node->front = q;
	node->rear = q->rear;
	q->rear->front = node;
	q->rear = node;
	q->size += 1;
	return 0;
}

static int pop_front(qNode* q)
{
	if(q->size == 0)
		return -1;
	qNode* node = q->front;
	q->front->front->rear = q->front->rear;
	q->front = q->front->front;
	free(node);
	q->size -= 1;
	return 0;
}

static qNode* front(qNode* q)
{
	return q->front;
}

static bool is_empty(qNode* q)
{
	return q->size == 0;
}

static int clear(qNode* q)
{
	if(q->size == 0)
		return -1;
	qNode* tmp = NULL;
	while(q->front != q)
	{
		tmp = q->front;
		q->front = q->front->front;
		free(tmp);
		q->size -= 1;
	}
	return 0;
}

Queue* NewQueue(size_t max_size)
{
	Queue* res = (Queue*)malloc(sizeof(Queue));
	res->queue = NewNode();
	res->push_back = push_back;
	res->pop_front = pop_front;
	res->front = front;
	res->is_empty = is_empty;
	res->clear = clear;
	limit_queue_size = max_size;
	return res;
}

void DeleteQueue(Queue* q)
{
	q->clear(q->queue);
	if(q->queue->size == 0)
		free(q->queue);
	free(q);
}
